﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NBusiness.Data.Providers.SqlServer.Query;
using NBusiness.Query.Testing.Mock;

namespace NBusiness.Query.Testing
{
    [TestClass]
    class QueryTests
    {
        [TestMethod]
        public void SqlGoTest()
        {
            IStatement sqlGo = new SqlGo();
            Assert.AreEqual("GO", sqlGo.ToSql());
        }

        [TestMethod]
        public void MultiStatementTest()
        {
            SqlTable example = new SqlTable("Example");
            SqlColumn text = new SqlColumn("Text", example);

            SqlQuery query = new SqlQuery();
            query.Statements.Add(new SqlSelect().From(example).Where(text == "one"));
            query.Statements.Add(new SqlSelect().From(example).Where(text == "two"));

            string expected = "SELECT * FROM [Example] AS [A] WHERE ([A].[Text]='one')\r\nSELECT * FROM [Example] AS [A] WHERE ([A].[Text]='two')";
            string actual = query.ToSql();

            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void TransactionalInsert()
        {
            SqlTable example = new SqlTable("Example");
            SqlColumn text = new SqlColumn("Text", example);
            SqlParameter p1 = new SqlParameter("p1");
            SqlParameter p2 = new SqlParameter("p2");

            SqlQuery query = new SqlQuery();
            query.Insert().Into(example, text).Values(p1);
            query.Go();
            query.Insert().Into(example, text).Values(p2);
            query.Go();

            string expected = "INSERT INTO [Example] ([Text]) VALUES (@p1)\r\nGO\r\nINSERT INTO [Example] ([Text]) VALUES (@p2)\r\nGO";
            string actual = query.ToSql();

            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void FluentSelect()
        {
            SqlQuery query = new SqlQuery();
            ISelect expected = query.Select();

            Assert.AreEqual(1, query.Statements.Count);
            
            ISelect actual = query.Statements[0] as ISelect;
            Assert.AreSame(expected, actual);
        }

        [TestMethod]
        public void FluentInsert()
        {
            SqlQuery query = new SqlQuery();
            IInsert expected = query.Insert();

            Assert.AreEqual(1, query.Statements.Count);

            IInsert actual = query.Statements[0] as IInsert;
            Assert.AreSame(expected, actual);
        }

        [TestMethod]
        public void FluentGo()
        {
            SqlQuery query = new SqlQuery();
            IStatement expected = query.Go();

            Assert.AreEqual(1, query.Statements.Count);

            IStatement actual = query.Statements[0] as IStatement;
            Assert.AreSame(expected, actual);
        }

        [TestMethod]
        public void FluentDelete()
        {
            SqlQuery query = new SqlQuery();
            IDelete expected = query.Delete();

            Assert.AreEqual(1, query.Statements.Count);

            IDelete actual = query.Statements[0] as IDelete;
            Assert.AreSame(expected, actual);
        }

        [TestMethod]
        public void FluentUpdate()
        {
            SqlQuery query = new SqlQuery();
            IUpdate expected = query.Update();

            Assert.AreEqual(1, query.Statements.Count);

            IUpdate actual = query.Statements[0] as IUpdate;
            Assert.AreSame(expected, actual);
        }

        [TestMethod]
        public void TestLoad()
        {
            bool loaded = false;
            IQuery query = new SqlQuery();
            query.Load += l => loaded = true;
            (query as SqlQuery).OnLoad(new MockLoader());
            Assert.IsTrue(loaded);
        }
    }
}
